home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / Misc / ytalk / Source / user.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  5.5 KB  |  250 lines

  1. /* user.c - YTalk user database module - YTalk V2.0 */
  2.  
  3. /*               NOTICE
  4.  *
  5.  * Copyright (c) 1990 Britt Yenne.  All rights reserved.
  6.  * 
  7.  * This software is provided AS-IS.  The author gives no warranty,
  8.  * real or assumed, and takes no responsibility whatsoever for any 
  9.  * use or misuse of this software, or any damage created by its use
  10.  * or misuse.
  11.  * 
  12.  * This software may be freely copied and distributed provided that
  13.  * no part of this NOTICE is deleted or edited in any manner.
  14.  * 
  15.  */
  16.  
  17. /* Mail comments or questions to yenne@ccwf.cc.utexas.edu */
  18.  
  19. #include "ytalk.h"
  20. #include <sys/file.h>
  21. #include <netdb.h>
  22. #include <stdio.h>
  23.  
  24. extern char myhost[100];    /* caller's host name */
  25. extern int errno;        /* system error number */
  26. extern CTL_MSG msg;        /* for communication with talk daemon */
  27.  
  28. person p[MAXC];        /* those in the conversation */
  29. int pnum = 0;        /* number of current conversationalists */
  30. int fdp[100];        /* for translating file numbers to user numbers */
  31.  
  32. extern char errstr[100], estr[100];    /* temporary string storage */
  33. extern long doalarm;    /* set if there is housekeeping to do */
  34. extern cpack crec;    /* for inter-YTalk communication */
  35. extern fd_set fdset;    /* main fdset for select() */
  36. extern char edit[4];    /* edit keys */
  37.  
  38. /* finduser locates a user in the user list, if he exists.
  39.  */
  40. finduser(str)
  41. char *str;
  42. {
  43.     char *hisname, *hishost;
  44.     int n, x;
  45.  
  46.     hishost = NULL;
  47.     hisname = str;
  48.     for(; *str; str++)
  49.     if(*str == '@')
  50.     {
  51.         *str = '\0';
  52.         hishost = str+1;
  53.         break;
  54.     }
  55.     for(n = 0; n < pnum; n++)
  56.     {
  57.     if(strncmp(p[n].name, hisname, NAMELEN) != 0)
  58.         continue;
  59.     if(hishost != NULL)
  60.         if(strncmp(p[n].host, hishost, HOSTLEN) != 0)
  61.         continue;
  62.     break;
  63.     }
  64.     if(n >= pnum)
  65.     {
  66.     if(hishost == NULL)
  67.         sprintf(errstr, "%s: Not in session", hisname);
  68.     else
  69.         sprintf(errstr, "%s@%s: Not in session", hisname, hishost);
  70.     errno = 0;
  71.     panic(errstr);
  72.     return -1;
  73.     }
  74.     return n;
  75. }
  76.  
  77. /* killuser destroys a user by name.
  78.  */
  79. killuser(str)
  80. char *str;
  81. {
  82.     int n;
  83.     if((n = finduser(str)) < 0)
  84.     return;
  85.     deluser(n);
  86. }
  87.  
  88. /* deluser destroys all loose ends about a current conversation and removes
  89.  * the user from the user list.
  90.  */
  91. deluser(i)
  92. {
  93.     if(i < 0 || i >= pnum)
  94.     return;
  95.     FD_CLR(p[i].sfd, &fdset);
  96.     close(p[i].sfd);
  97.     fdp[p[i].sfd] = -1;
  98.     if(p[i].win >= 0)
  99.     del_window(p[i].win);
  100.     if(p[i].ffd != -1)
  101.     close(p[i].ffd);
  102.     pnum--;
  103.     for(; i < pnum; i++)
  104.     {
  105.     p[i] = p[i+1];
  106.     fdp[p[i].sfd] = i;
  107.     }
  108. }
  109.  
  110. /* outfile opens an output file and attaches it to a particular user so
  111.  * that all input from that user is copied to the output file.
  112.  */
  113. outfile(str, file)
  114. char *str, *file;
  115. {
  116.     int n;
  117.  
  118.     if((n = finduser(str)) < 0)
  119.     return;
  120.     if(p[n].ffd != -1)
  121.     {
  122.     sprintf(errstr, "%s already has an output file", str);
  123.     panic(errstr);
  124.     return;
  125.     }
  126.     if((p[n].ffd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
  127.     {
  128.     sprintf(errstr, "Cannot open %s", file);
  129.     panic(errstr);
  130.     p[n].ffd = -1;
  131.     return;
  132.     }
  133. }
  134.  
  135. /* newuser adds a new user to the conversation, either by accepting that
  136.  * user's invitation, or instigating an invitation.  If the user in
  137.  * question is using YTalk, newuser() will attempt to connect to his
  138.  * auto-invitation port and forego the annoying annoucement message.
  139.  */
  140. newuser(str, ring)
  141. char *str, ring;
  142. {
  143.     char *hisname, *hishost, *histty;
  144.     struct hostent *host;
  145.     int n, x;
  146.  
  147.     if(pnum+1 >= MAXC)
  148.     {
  149.     errno = 0;
  150.     panic("Too many people in conversation!\n");
  151.     return;
  152.     }
  153.  
  154.     /* First break down the username into login name and login host,
  155.      * assuming our host as a default.
  156.      */
  157.  
  158.     hishost = myhost;
  159.     histty  = "";
  160.     hisname = str;
  161.     for(; *str; str++)
  162.     {
  163.     if(*str == '@')
  164.     {
  165.         *str = '\0';
  166.         hishost = str+1;
  167.     }
  168.     if(*str == '#')
  169.     {
  170.         *str = '\0';
  171.         histty = str+1;
  172.     }
  173.     }
  174.  
  175.     if((host = (struct hostent *) lookup_host(hishost)) == 0)
  176.     {
  177.     sprintf(errstr, "Unknown host: %s\n", hishost);
  178.     panic(errstr);
  179.     return;
  180.     }
  181.     strncpy(msg.r_name, hisname, NAME_SIZE);
  182.     strncpy(msg.r_tty, "", TTY_SIZE);
  183.     strncpy(p[pnum].name, hisname, NAMELEN);
  184.     strncpy(p[pnum].host, host->h_name, HOSTLEN);
  185.     strncpy(p[pnum].tty, histty, TTY_SIZE);
  186.     p[pnum].ffd = -1;
  187.     p[pnum].flags = 0;
  188.     p[pnum].win = -1;
  189.     p[pnum].last_ring = time((time_t *)0);
  190.     p[pnum].a_id = 0;
  191.     p[pnum].id = 0;
  192.  
  193.     for(n = 0; n < pnum; n++)
  194.     if(strncmp(p[n].name, hisname, NAMELEN) == 0)
  195.     {
  196.         if(p[n].flags & P_CONTACT)
  197.         sprintf(errstr, "%s is already in this session", hisname);
  198.         else
  199.         sprintf(errstr, "%s already being rung", hisname);
  200.         errno = 0;
  201.         panic(errstr);
  202.         return;
  203.     }
  204.  
  205.     /* Check for a normal invitation */
  206.  
  207.     while((n = send_dgram(p[pnum].host, LOOK_UP, pnum)) == 0)
  208.     {
  209.     /* We are expected... */
  210.     p[pnum].flags = 0;
  211.     if((x = connect_to(pnum)) < 0)
  212.     {
  213.         if(x == -2)
  214.         {
  215.         send_dgram(p[pnum].host, DELETE, pnum);
  216.         continue;
  217.         }
  218.         return;
  219.     }
  220.     fdp[p[pnum].sfd] = pnum;
  221.     FD_SET(p[pnum].sfd, &fdset);
  222.     bcopy(edit, errstr, 3);
  223.     errstr[0] = RUBDEF;
  224.     write(p[pnum].sfd, errstr, 3);    /* send the edit keys */
  225.     pnum++;
  226.     return;
  227.     }
  228.     if(n == -1)
  229.     return;
  230.  
  231.     /* Leave an invitation for him, and announce ourselves. */
  232.  
  233.     strncpy(msg.r_tty, histty, TTY_SIZE);
  234.     doalarm = 1;    /* set the housecleaning flag */
  235.     p[pnum].flags = 0;
  236.     if(newsock(pnum) != 0)
  237.     return;
  238.     (void) send_dgram(myhost, LEAVE_INVITE, pnum);
  239.     if(ring)
  240.     if((announce(p[pnum].host, pnum)) != 0)
  241.     {
  242.         send_dgram(myhost, DELETE, pnum);
  243.         close(p[pnum].sfd);
  244.         return;
  245.     }
  246.     fdp[p[pnum].sfd] = pnum;
  247.     FD_SET(p[pnum].sfd, &fdset);
  248.     pnum++;
  249. }
  250.